Skip to content

Prune real-time branch of deep hierarchical caggs - #10175

Merged
melihmutlu merged 1 commit into
timescale:mainfrom
melihmutlu:fix-10071
Jul 22, 2026
Merged

Prune real-time branch of deep hierarchical caggs#10175
melihmutlu merged 1 commit into
timescale:mainfrom
melihmutlu:fix-10071

Conversation

@melihmutlu

Copy link
Copy Markdown
Member

A single application of ts_transform_time_bucket_comparison() strips
only the outermost time_bucket() from a comparison. In a hierarchical
continuous aggregate the bucket input is itself another time_bucket()
call. The real-time branch could not be proven empty and the refresh
re-scanned the whole raw un-materialized tail of the base hypertable.

Add ts_transform_nested_time_bucket_comparison(), which applies the
single-level transform repeatedly until the bound is expressed on the
raw column. Only the original qual and the fully reduced qual are kept;
the intermediate levels have no consumer.

Fixes: #10071

@melihmutlu
melihmutlu force-pushed the fix-10071 branch 2 times, most recently from 8776152 to 18649b5 Compare June 30, 2026 20:13
@codecov

codecov Bot commented Jun 30, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@melihmutlu
melihmutlu marked this pull request as ready for review June 30, 2026 20:31
@melihmutlu
melihmutlu requested review from a team and Copilot June 30, 2026 20:31
@github-actions

Copy link
Copy Markdown

@Poroma-Banerjee, @natalya-aksman: please review this pull request.

Powered by pull-review

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes a performance/planning issue for deep (3+ level) hierarchical real-time continuous aggregates by fully unwrapping nested time_bucket() comparisons into constraints on the underlying raw time column, enabling real-time branch pruning and better chunk exclusion at any nesting depth.

Changes:

  • Added ts_transform_nested_time_bucket_comparison() to repeatedly apply the existing single-level time_bucket() comparison transform until no further unwrapping is possible.
  • Switched hypertable expansion and chunk-append runtime constification to use the nested transform so deep hierarchical caggs get fully reduced constraints.
  • Added a regression test (+ expected output) validating that the real-time branch is pruned (“One-Time Filter: false”) for 3- and 4-level hierarchical real-time caggs.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated no comments.

Show a summary per file
File Description
tsl/test/sql/CMakeLists.txt Registers the new hierarchical real-time cagg regression test.
tsl/test/sql/cagg_hierarchical_realtime.sql New regression test reproducing #10071 and validating pruning for 2/3/4 levels.
tsl/test/expected/cagg_hierarchical_realtime.out Expected EXPLAIN plans showing real-time branch pruning at deeper nesting.
src/planner/planner.h Exposes the new nested transform helper.
src/planner/expand_hypertable.c Implements nested transform and uses it in qual processing / timebucket annotation / simplified restrictions.
src/nodes/chunk_append/exec.c Uses nested transform during runtime constification to improve chunk exclusion with nested buckets.
.unreleased/fix_10071 Adds release note entry for the fix.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@melihmutlu
melihmutlu force-pushed the fix-10071 branch 2 times, most recently from c790eff to 5f4cd4b Compare July 7, 2026 09:38
A single application of ts_transform_time_bucket_comparison() strips
only the outermost time_bucket() from a comparison. In a hierarchical
continuous aggregate the bucket input is itself another time_bucket()
call. The real-time branch could not be proven empty and the refresh
re-scanned the whole raw un-materialized tail of the base hypertable.

Add ts_transform_nested_time_bucket_comparison(), which applies the
single-level transform repeatedly until the bound is expressed on the
raw column. Only the original qual and the fully reduced qual are kept;
the intermediate levels have no consumer.

Fixes: timescale#10071
@melihmutlu
melihmutlu enabled auto-merge (squash) July 22, 2026 10:27
@melihmutlu
melihmutlu merged commit 5ebc0fa into timescale:main Jul 22, 2026
60 checks passed
@timescale-automation

Copy link
Copy Markdown
Member

Automated backport to 2.28.x not done: cherry-pick failed.

Git status

HEAD detached at origin/2.28.x
You are currently cherry-picking commit 5ebc0fab5.
  (fix conflicts and run "git cherry-pick --continue")
  (use "git cherry-pick --skip" to skip this patch)
  (use "git cherry-pick --abort" to cancel the cherry-pick operation)

Changes to be committed:
	new file:   .unreleased/pr_10175
	modified:   src/nodes/chunk_append/exec.c
	modified:   src/planner/expand_hypertable.c
	modified:   src/planner/planner.h
	new file:   tsl/test/expected/cagg_hierarchical_realtime-16.out
	new file:   tsl/test/expected/cagg_hierarchical_realtime-17.out
	new file:   tsl/test/expected/cagg_hierarchical_realtime-18.out
	new file:   tsl/test/expected/cagg_hierarchical_realtime-19.out
	new file:   tsl/test/sql/cagg_hierarchical_realtime.sql.in

Unmerged paths:
  (use "git add <file>..." to mark resolution)
	both modified:   tsl/test/sql/CMakeLists.txt


Job log

@timescale-automation timescale-automation added the auto-backport-not-done Automated backport of this PR has failed non-retriably (e.g. conflicts) label Jul 22, 2026
@melihmutlu
melihmutlu deleted the fix-10071 branch July 22, 2026 10:59
@melihmutlu melihmutlu added backported-2.29.x force-auto-backport Automatically backport this PR or fix of this issue, even if it's not marked as "bug" and removed backported-2.29.x auto-backport-not-done Automated backport of this PR has failed non-retriably (e.g. conflicts) labels Jul 27, 2026
timescale-automation pushed a commit that referenced this pull request Jul 27, 2026
A single application of ts_transform_time_bucket_comparison() strips
only the outermost time_bucket() from a comparison. In a hierarchical
continuous aggregate the bucket input is itself another time_bucket()
call. The real-time branch could not be proven empty and the refresh
re-scanned the whole raw un-materialized tail of the base hypertable.

Add ts_transform_nested_time_bucket_comparison(), which applies the
single-level transform repeatedly until the bound is expressed on the
raw column. Only the original qual and the fully reduced qual are kept;
the intermediate levels have no consumer.

Fixes: #10071
(cherry picked from commit 5ebc0fa)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backported-2.29.x force-auto-backport Automatically backport this PR or fix of this issue, even if it's not marked as "bug" released-2.29.0 Released in 2.29.0

Projects

None yet

5 participants